package bookstore.manager.impl;

import bookstore.bound.auth.EnrollForm;
import bookstore.bound.auth.UsernameForm;
import bookstore.bound.user.UserDisp;
import bookstore.manager.UserManager;
import bookstore.model.User;
import bookstore.model.UserProfile;
import bookstore.repository.UserProfileDao;
import bookstore.repository.UserRepository;
import bookstore.utils.CryptoUtils;
import bookstore.utils.SessionUtils;
import bookstore.utils.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.util.*;

@Service
public class UserManagerImpl implements UserManager {
    @Autowired
    protected UserRepository userRepository;
    @Autowired
    protected UserProfileDao userProfileDao;

    protected SessionUtils sessionUtils = new SessionUtils();
    protected CryptoUtils cryptoUtils = new CryptoUtils();


    @Override
    public Map enroll(HttpSession session, EnrollForm form) {
        System.out.println(this.getClass().getName());

        User user = new User();
        user.setEmail(form.getEmail());
        user.setTel(form.getTel());
        user.setPwd(form.getPass());

        Map<String, Object> rsp = new HashMap<>();
        try {
            User temp = userRepository.save(user);
            Long uid = temp.getUserid();
            temp.setPwd(cryptoUtils.encrypt(uid, form.getPass()));

            Optional<UserInfo> info = sessionUtils.setProfile(session, userRepository.save(temp));

            rsp.put("success", info.map(userInfo -> userInfo.getUserId()).isPresent());
            info.ifPresent(userInfo -> rsp.put("profile", userInfo));
        } catch (Exception err) {
            rsp.put("success", false);

            String msg = err.getMessage();
            if (msg.indexOf("mail") > -1) {
                msg = "邮箱已被占用";
            } else if (msg.indexOf("tel") > -1) {
                msg = "手机号已被注册";
            }
            rsp.put("msg", msg);
        }

        return rsp;
    }


    @Override
    public Map checkUsername(String username) {
        Optional<User> opt = userRepository.findByUsername(username);

        Map<String, Boolean> rsp = new HashMap<>();
        rsp.put("available", !opt.isPresent());
        return rsp;
    }

    @Override
    public Map getUserProfile(HttpSession session) {
        Long uid = sessionUtils.getProfile(session).map(UserInfo::getUserId).get();

        Optional<UserProfile> profile = userProfileDao.findById(uid);

        Map<String, Object> rsp = new HashMap<>();
        rsp.put("profile", profile);
        return rsp;
    }

    @Override
    public Map setUsername(HttpSession session, UsernameForm form) {
        Map<String, Object> rsp = checkUsername(form.getUsername());
        if ((Boolean) rsp.get("available")) {
            User user = sessionUtils.getProfile(session)
                    .map(UserInfo::getUserId)
                    .flatMap(userRepository::findById).get();
            user.setUsername(form.getUsername());
            sessionUtils.setProfile(session, userRepository.save(user));

            Optional<UserInfo> info = sessionUtils.getProfile(session);
            rsp.put("success", info.map(userInfo -> userInfo.getUsername()).isPresent());
            info.ifPresent(userInfo -> rsp.put("profile", userInfo));
        }
        return rsp;
    }

    @Override
    public Map updateProfile(HttpSession session, UserProfile userProfile) {
        Map<String, Object> rsp = new HashMap<>();
        try {
            Long uid = sessionUtils.getProfile(session).map(UserInfo::getUserId).get();
            userProfile.setUserid(uid);
            userProfileDao.save(userProfile);
            rsp.put("success", true);
        } catch (Exception err) {
            rsp.put("success", false);
            rsp.put("msg", err.getMessage());
        }
        return rsp;
    }

    @Override
    public Set<UserDisp> getAllUsers() {
        Set<UserDisp> lst = new HashSet<>();

        for (User user : userRepository.findAll()) {
            lst.add(new UserDisp((user)));
        }

        return lst;
    }

    // Update
    @Override
    public Map updateTel(Long id, String tel) {
        User user = userRepository.findById(id).get();
        user.setTel(tel);
        userRepository.save(user);

        Map<String, Boolean> rsp = new HashMap<>();
        rsp.put("success", user.getTel() == tel);
        return rsp;
    }

    @Override
    public Map updateActivate(Long id, boolean activate) {
        User user = userRepository.findById(id).get();
        user.setActivate(activate);
        userRepository.save(user);

        Map<String, Boolean> rsp = new HashMap<>();
        rsp.put("success", user.getActivate() == activate);
        return rsp;
    }

    @Override
    public Map updateStaff(Long id, boolean staff) {
        User user = userRepository.findById(id).get();
        user.setStaff(staff);
        userRepository.save(user);

        Map<String, Boolean> rsp = new HashMap<>();
        rsp.put("success", user.getStaff() == staff);
        return rsp;
    }

    @Override
    public Map updateAvailable(Long id, boolean available) {
        User user = userRepository.findById(id).get();
        user.setAvailable(available);
        userRepository.save(user);

        Map<String, Boolean> rsp = new HashMap<>();
        rsp.put("success", user.getAvailable() == available);
        return rsp;
    }

    // Delete
    @Override
    public Map delete(Long id) {
        User user = userRepository.findById(id).get();
        userRepository.delete(user);

        Map<String, Boolean> rsp = new HashMap<>();
        rsp.put("success", !userRepository.findById(id).isPresent());
        return rsp;
    }

}
